/* 
   （1）什么是函数对象？
   （2）如何使用函数指针？
   （3）如何使用成员指针访问运算符 */
#include <iostream>
using std::cout;
using std::endl;
//内层类
//外层类
class InLayer{
private:
    int m_data;
public:
    InLayer(int data = 0)
        :m_data(data)
    {}
    void get_data() {
        cout << m_data << endl;
    }
};//end of class InLayer

class OutLayer{
private:
    InLayer * m_inlayer;
public:
    OutLayer(InLayer * p)
        :m_inlayer(p)
    {}
    ~OutLayer() {
        if (m_inlayer) {
            delete m_inlayer;
            m_inlayer = nullptr;
        }
    }
    //重载->
    InLayer * operator->() {
        return m_inlayer;
    }
    //重载*
    InLayer operator*() {
        return *m_inlayer;
    }
    // 重载()
    void operator()() {
        cout << "operator ()" << endl;
    }
    void func() {
        cout << "func" << endl;
    }

};//end of class OutLayer
  //函数对象
void test1() {
    OutLayer f(new InLayer());
    f();
}
//函数指针
void test2() {
    OutLayer p(new InLayer);
    void (OutLayer::*f)() = &OutLayer::func;
    (p.*f)();
}
//成员指针访问运算符
void test3() {
    OutLayer p(new InLayer());
    typedef void(OutLayer::*F)();
    F f = &OutLayer::func;
    (p.*f)();
    OutLayer * p1 = new OutLayer{new InLayer()};
    (p1->*f)();
    delete p1;


}
int main()
{
    test1();
    cout << "------------" << endl;
    test2();
    cout << "------------" << endl;
    test3();
    cout << "------------" << endl;
    OutLayer outlayer(new InLayer(5));
    /* outlayer->get_data(); */
    outlayer->get_data();
    /* (*outlayer).get_data(); */
    (*outlayer).get_data();
    return 0;
}

